package com.hanbang.maige.widget.countdown;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;

import com.hanbang.maige.R;
import com.hanbang.maige.utils.other.StringUtils;

/**
 * Countdown View
 * Created by iWgang on 15/9/16.
 * https://github.com/iwgang/CountdownView
 */
public class CountdownView extends View {
    private final int[] mAttr = {android.R.attr.textSize, android.R.attr.textColor};

    private CustomCountDownTimer mCustomCountDownTimer;
    private OnCountdownListener mOnCountdownListener;

    private Paint timeTextPaint, mSuffixPaint;
    private float baselineTime, baselineSuffix;
    private int timeTextColor = getResources().getColor(R.color.white);
    float timeTextSize = sip(15);
    private long mRemainTime;

    private int mTextHeight;

    public int mDay, mHour, mMinute, mSecond, mMillisecond;

    protected String mSuffixDay = "天 ", mSuffixHour = "时 ", mSuffixMinute = "分 ", mSuffixSecond = "秒";
    protected float mSuffixDayTextWidth, mSuffixHourTextWidth, mSuffixMinuteTextWidth, mSuffixSecondTextWidth;


    //当时间大于10天显示具体的时间
    private String dataStr;
    //倒计时结束显示的文本
    private String endShowData;
    private int maxDay = 10;
    //显示指定的文本
    private boolean isShowData = false;
    private boolean isStartLayout = false;


    public CountdownView(Context context) {
        this(context, null);
    }

    public CountdownView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CountdownView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        initView(context, attrs);

    }

    private int sip(int sip) {
        final float fontScale = getResources().getDisplayMetrics().scaledDensity;

        return (int) (sip * fontScale + 0.5f);
    }

    private void initView(Context context, AttributeSet attrs) {

        TypedArray array = getContext().obtainStyledAttributes(attrs, mAttr);
        timeTextSize = array.getDimension(0, sip((int) timeTextSize));
        timeTextColor = array.getColor(1, timeTextColor);
        array.recycle();
        timeTextPaint = new Paint();
        timeTextPaint.setColor(timeTextColor);
        timeTextPaint.setTextAlign(Paint.Align.LEFT);
        timeTextPaint.setTextSize(timeTextSize);
        timeTextPaint.setAntiAlias(true);
        Rect rect = new Rect();
        timeTextPaint.getTextBounds("00", 0, 2, rect);
        mTextHeight = rect.height();
        mSuffixPaint = new Paint();
        mSuffixPaint.setColor(timeTextColor);
        mSuffixPaint.setTextAlign(Paint.Align.LEFT);
        mSuffixPaint.setTextSize(timeTextSize * 0.6f);
        mSuffixPaint.setAntiAlias(true);
        setSuffixSize();
    }

    private void setSuffixSize() {
        mSuffixDayTextWidth = getTextWidth(mSuffixPaint, mSuffixDay);
        mSuffixHourTextWidth = getTextWidth(mSuffixPaint, mSuffixHour);
        mSuffixMinuteTextWidth = getTextWidth(mSuffixPaint, mSuffixMinute);
        mSuffixSecondTextWidth = getTextWidth(mSuffixPaint, mSuffixSecond);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        float width = 0;
        int height = getPaddingTop() + getPaddingBottom();
        width = getPaddingLeft() + getPaddingRight();
        if (isShowData) {
            width += getTextWidth(timeTextPaint, dataStr);
        } else {
            if (mDay > 0) {
                width += getTextWidth(timeTextPaint, getDayString());
                width += mSuffixDayTextWidth;
            }
            width += getTextWidth(timeTextPaint, getHourString());
            width += mSuffixHourTextWidth;

            width += getTextWidth(timeTextPaint, getMinString());
            width += mSuffixMinuteTextWidth;
            if (mDay <= 0) {
                width += getTextWidth(timeTextPaint, getSecString());
                width += mSuffixSecondTextWidth;
            }

        }
        height += mTextHeight;
        setMeasuredDimension((int) Math.ceil(width), height);

        Paint.FontMetricsInt fontMetrics = timeTextPaint.getFontMetricsInt();//文字的4根线，baseLine为0，top为负值， bottom为正数
        baselineTime = (height - fontMetrics.top - fontMetrics.bottom) / 2.0f;
        Paint.FontMetricsInt fontMetricsSuffix = mSuffixPaint.getFontMetricsInt();//文字的4根线，baseLine为0，top为负值， bottom为正数
        baselineSuffix = (height - fontMetricsSuffix.top - fontMetricsSuffix.bottom) / 2.0f;
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (isShowData) {
            drawFomatData(canvas);
        } else {
            drawCountdown(canvas);
        }

    }

    private void drawFomatData(Canvas canvas) {
        if (dataStr != null) {
            canvas.drawText(dataStr, getPaddingLeft(), baselineTime, timeTextPaint);
        }
    }

    private void drawCountdown(Canvas canvas) {


        float leftSize = getPaddingLeft();
        String strDay = getDayString();
        String strhour = getHourString();
        String strMin = getMinString();
        String strsec = getSecString();

        if (mDay > 0) {
            canvas.drawText(strDay, leftSize, baselineTime, timeTextPaint);
            leftSize += getTextWidth(timeTextPaint, strDay);
            canvas.drawText(mSuffixDay, leftSize, baselineSuffix, mSuffixPaint);
            leftSize += mSuffixDayTextWidth;
        }
        canvas.drawText(strhour, leftSize, baselineTime, timeTextPaint);
        leftSize += getTextWidth(timeTextPaint, strhour);
        canvas.drawText(mSuffixHour, leftSize, baselineSuffix, mSuffixPaint);
        leftSize += mSuffixDayTextWidth;


        canvas.drawText(strMin, leftSize, baselineTime, timeTextPaint);
        leftSize += getTextWidth(timeTextPaint, strMin);
        canvas.drawText(mSuffixMinute, leftSize, baselineSuffix, mSuffixPaint);
        leftSize += mSuffixMinuteTextWidth;
        if (mDay <= 0) {
            canvas.drawText(strsec, leftSize, baselineTime, timeTextPaint);
            leftSize += getTextWidth(timeTextPaint, strsec);
            canvas.drawText(mSuffixSecond, leftSize, baselineSuffix, mSuffixPaint);
        }
    }

    public float getTextWidth(Paint paint, String str) {
        int iRet = 0;
        if (str != null && str.length() > 0) {
            int len = str.length();
            float[] widths = new float[len];
            paint.getTextWidths(str, widths);
            for (int j = 0; j < len; j++) {
                iRet += widths[j];
            }
        }
        return iRet;
    }


    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        pause();
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (mCustomCountDownTimer != null) {
            mCustomCountDownTimer.start();
        }
    }

    public void setEndShowData(String endShowData) {
        this.endShowData = endShowData;
    }

    public void setDataStr(String dataStr) {
        this.dataStr = dataStr;
    }

    /**
     * start countdown
     *
     * @param millisecond millisecond
     */
    public void start(long millisecond) {

        isShowData = millisecond <= 0;
        if (millisecond <= 0) {
            requestLayout();
            invalidate();
            return;
        }

        int day = (int) (millisecond / (1000 * 60 * 60 * 24));
        if (day >= maxDay && !StringUtils.isBlank(dataStr)) {
            isShowData = true;
            requestLayout();
            invalidate();
            return;
        }

        isStartLayout = true;
        if (null != mCustomCountDownTimer) {
            mCustomCountDownTimer.stop();
            mCustomCountDownTimer = null;
        }
        mCustomCountDownTimer = new CustomCountDownTimer(millisecond, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                updateShow(millisUntilFinished);
                if (null != mOnCountdownListener) {
                    mOnCountdownListener.onInterval(CountdownView.this, millisUntilFinished);
                }
            }

            @Override
            public void onFinish() {
                if (null != mOnCountdownListener) {
                    mOnCountdownListener.onEnd(CountdownView.this);
                }
                CountdownView.this.dataStr = endShowData;
                isShowData = true;
                requestLayout();
                invalidate();
            }
        };
        mCustomCountDownTimer.start();
    }

    /**
     * stop countdown
     */
    public void stop() {
        if (null != mCustomCountDownTimer) mCustomCountDownTimer.stop();
    }

    /**
     * pause countdown
     */
    public void pause() {
        if (null != mCustomCountDownTimer) mCustomCountDownTimer.pause();
    }

    /**
     * pause countdown
     */
    public void restart() {
        if (null != mCustomCountDownTimer) mCustomCountDownTimer.restart();
    }


    /**
     * set countdown end callback listener
     */
    public void setOnCountdownEndListener(OnCountdownListener onCountdownListener) {
        mOnCountdownListener = onCountdownListener;
    }

    public String getDayString() {
        return String.valueOf(mDay);
    }

    public String getHourString() {
        return String.format("%02d", mHour);
    }

    public String getMinString() {
        return String.format("%02d", mMinute);
    }

    public String getSecString() {
        return String.format("%02d", mSecond);
    }

    /**
     * get remain time
     *
     * @return remain time ( millisecond )
     */
    public long getRemainTime() {
        return mRemainTime;
    }

    public void updateShow(long ms) {
        this.mRemainTime = ms;


        int day = (int) (ms / (1000 * 60 * 60 * 24));
        int hour = (int) ((ms % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
        int minute = (int) ((ms % (1000 * 60 * 60)) / (1000 * 60));
        int second = (int) ((ms % (1000 * 60)) / 1000);
        int millisecond = (int) (ms % 1000);
        if (day != mDay) {
            requestLayout();
        }
        if (isStartLayout) {
            isStartLayout = false;
            requestLayout();
        }
        if (day > 0) {
            if (day >= maxDay) {
                isShowData = true;
                requestLayout();
            }
            if (minute != mMinute || hour != mHour) {
                setTimes(day, hour, minute, second, millisecond);
                invalidate();
            }
        } else {
            if (day == 0 && day != mDay) {
                requestLayout();
            }
            if (second != mSecond || minute != mMinute || hour != mHour) {
                setTimes(day, hour, minute, second, millisecond);
                invalidate();
            }
        }

    }


    public void setTimes(int day, int hour, int minute, int second, int millisecond) {
        mDay = day;
        mHour = hour;
        mMinute = minute;
        mSecond = second;
        mMillisecond = millisecond;

    }

    public interface OnCountdownListener {
        void onEnd(CountdownView cv);

        void onInterval(CountdownView cv, long remainTime);
    }


}
